package com.lcj.config;

import com.lcj.util.ThreadMdcUtils;
import lombok.RequiredArgsConstructor;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.MDC;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * <p>
 *
 * </p>
 *
 * @author: liuchangjun
 * @since: 2023/12/22 14:59
 */

@Configuration
@RequiredArgsConstructor
@EnableAsync
@EnableWebSocket
@MapperScan("com.lcj.mapper")
public class WebConfig implements WebMvcConfigurer {

    private final TraceIdInterceptor traceIdInterceptor;

    /**
     * <p>
     * 事件监听线程池
     * </p>
     *
     * @return 线程池
     */
    @Bean("eventListenerPool")
    public Executor eventListenerPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数量
        executor.setCorePoolSize(1);
        // 设置最大线程数量
        executor.setMaxPoolSize(2);
        // 设置队列最大长度
        executor.setQueueCapacity(100);
        // 设置线程空闲时间
        executor.setKeepAliveSeconds(60);
        // 设置线程前缀
        executor.setThreadNamePrefix("event-listener-thread-");
        // 设置线程工厂
        executor.setThreadFactory(Thread.ofVirtual().name("event-virtual-thread-", 0).factory());
        // 设置拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 设置线程装饰器
        executor.setTaskDecorator(runnable -> ThreadMdcUtils.wrapAsync(runnable, MDC.getCopyOfContextMap()));
        return executor;
    }


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(traceIdInterceptor).order(0);
    }


    /**
     * 注入ServerEndpointExporter，
     * 这个bean会自动注册使用了@ServerEndpoint注解声明的WebSocket Endpoint
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
